package main

import (
	"fmt"
	"log"
	"sync"
	"time"
)

type UserStat uint32

const (
	USERSTAT_UNKNOWN = iota
	USERSTAT_ONLINE
	USERSTAT_IN_VIDEO
)

const USER_ACTIVE_TIMEOUT = 15   //s
const USER_REMOVE_TIMEOUT = (60) //s

type UserContent struct {
	pid         int32      // user pk
	tp          int32      // user type
	stat        UserStat   // current status
	active_time int64      // last activity timestamp
	online_time int64      //
	enter_time  int64      //
	room        string     // room id
	device      string     // running device
	guahao      *guahao    // guahao
	user        *basicinfo // user
}

var UserList map[string]*UserContent
var Mutex *sync.Mutex

func GetOnlineUser() []*UserContent {
	users := make([]*UserContent, 0)
	Mutex.Lock()
	defer Mutex.Unlock()
	for _, v := range UserList {
		users = append(users, v)
	}
	return users
}

func GetOnlineUserByShiPin(room string) []*UserContent {
	users := make([]*UserContent, 0)
	Mutex.Lock()
	defer Mutex.Unlock()
	for _, v := range UserList {
		if v.stat == USERSTAT_IN_VIDEO && v.room == room {
			users = append(users, v)
		}
	}
	return users
}

func UserStatUpdate(stat UserContent) {
	log.Println("UserStatUpdate:", stat)
	Mutex.Lock()
	defer Mutex.Unlock()
	user := fmt.Sprint(stat.pid) + fmt.Sprint(stat.tp) + fmt.Sprint(stat.device)
	if u, ok := UserList[user]; !ok {
		log.Println(u, ok)
		stat.online_time = time.Now().Unix()
		// log.Println("First update:", stat)
	} else {
		// log.Println("Not First update:", stat)
		stat.online_time = u.online_time
		stat.enter_time = u.enter_time
		if u.stat == USERSTAT_UNKNOWN {
			stat.online_time = time.Now().Unix()
		}
		if u.stat == USERSTAT_ONLINE && stat.stat == USERSTAT_IN_VIDEO {
			stat.enter_time = time.Now().Unix()
		}
	}
	stat.active_time = time.Now().Unix()
	UserList[user] = &stat
}

func UserStatScan() {
	for {
		time.Sleep(1 * time.Second)
		Mutex.Lock()
		for k, v := range UserList {
			// log.Println("User Stat:", k, v)
			if time.Now().Unix() > v.active_time+USER_ACTIVE_TIMEOUT {
				v.stat = USERSTAT_UNKNOWN
				log.Println("User Offline:", k, v)
			}
			if time.Now().Unix() > v.active_time+USER_REMOVE_TIMEOUT {
				delete(UserList, k)
			}
		}
		Mutex.Unlock()
	}
}

func UserStatInit() {
	Mutex = &sync.Mutex{}
	UserList = make(map[string]*UserContent)
	go UserStatScan()
}
